﻿using System;
#if DEBUG
using System.Diagnostics;
#endif // #if DEBUG
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using FRL.DebtChased.Extensions;
using FRL.DebtChased.Repository;
using FRL.DebtChased.Silverlight.Library;
using FRL.DebtChased.Types;

namespace FRL.DebtChased.ChaseWorkspace
{

	/// <summary>
	/// Declaration of InstalmentStartDateCtrl class
	/// Frequency and start date editor for instalment plan
	/// </summary>
	public partial class InstalmentStartDateCtrl : UserControl
	{

		/////////////////////////////////////////////////////////////
		// Delegates and Events

		public event EventHandler ParametersChanged;

		/////////////////////////////////////////////////////////////
		// Attributes

		private Frequency.ePeriod m_Period = Frequency.ePeriod.Weekly;

		private bool m_bBlockEvents = true;

		/////////////////////////////////////////////////////////////
		// Construction

		public InstalmentStartDateCtrl()
		{

			// Load xaml resources
			InitializeComponent();

			// Setup animations
			(animDropForms.Children[0] as DoubleAnimation).To = gridForms.MaxHeight;

			// Set controls - cboPeriod
			cboPeriod.Items.Add(new ComboBoxObject("Weekly", (int)Frequency.ePeriod.Weekly, null));
			cboPeriod.Items.Add(new ComboBoxObject("Biweekly", (int)Frequency.ePeriod.Biweekly, null));
			cboPeriod.Items.Add(new ComboBoxObject("Monthly", (int)Frequency.ePeriod.Monthly, null));
			cboPeriod.SelectedIndex = 0;

			// Set controls - cboGenetive
			cboGenetive.Items.Add(new ComboBoxObject("First", 1, null));
			cboGenetive.Items.Add(new ComboBoxObject("Second", 2, null));
			cboGenetive.Items.Add(new ComboBoxObject("Third", 3, null));
			cboGenetive.Items.Add(new ComboBoxObject("Fourth", 4, null));
			cboGenetive.SelectedIndex = 0;

			// Set controls - cboMonthDayWeekday
			cboMonthDayWeekday.Items.Add(new ComboBoxObject("Mon", (int)DayOfWeek.Monday, null));
			cboMonthDayWeekday.Items.Add(new ComboBoxObject("Tue", (int)DayOfWeek.Tuesday, null));
			cboMonthDayWeekday.Items.Add(new ComboBoxObject("Wed", (int)DayOfWeek.Wednesday, null));
			cboMonthDayWeekday.Items.Add(new ComboBoxObject("Thu", (int)DayOfWeek.Thursday, null));
			cboMonthDayWeekday.Items.Add(new ComboBoxObject("Fri", (int)DayOfWeek.Friday, null));
			cboMonthDayWeekday.SelectedIndex = 0;

			// Set controls - cboMonthDayOfMonth
			for (int i1 = 1; i1 <= 31; i1++)
				cboMonthDayOfMonth.Items.Add(new ComboBoxObject(i1.ToString(), i1, null));
			cboMonthDayOfMonth.SelectedIndex = 0;

			// Set data picker
			pickerStartDate.SelectedDate = DateTime.Now;

			// Init the radio
			radMonthByDate.IsChecked = true;

			// Clear flag
			m_bBlockEvents = false;

			// Setup controls
			_setupControls();

		}

		private void UserControl_Loaded(object sender, RoutedEventArgs e)
		{

			// Update summary
			_updateSummary();

		}

		/////////////////////////////////////////////////////////////
		// Event Handlers

		private void cboPeriod_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{

			// If blocking events...
			if (m_bBlockEvents)
				return;

			// Retain the period
			Frequency.ePeriod Period = (Frequency.ePeriod) (cboPeriod.SelectedItem as ComboBoxObject).ItemData;
			m_Period = (m_Period & Frequency.ePeriod.Monthly_Param_Mask) | Period;

			// Setup controls
			_setupControls();

			// Update summary
			_updateSummary();

			// Send event
			if (ParametersChanged != null)
				ParametersChanged(this, e);

		}

		private void cboMonthDayOfMonth_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{

			// If blocking events...
			if (m_bBlockEvents)
				return;

			// block events
			m_bBlockEvents = true;
			{

				// Check the mode
				radMonthByDate.IsChecked = true;

				// Calculate start date
				int iDayOfMonth = (cboMonthDayOfMonth.SelectedItem as ComboBoxObject).ItemData;
				iDayOfMonth = ExtensionsForDates.CalcNearestValidDay(DateTime.Now.Year, DateTime.Now.Month, iDayOfMonth);
				pickerStartDate.SelectedDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, iDayOfMonth);

				// Set month-by-week controls
				_setMonthByWeekControls(pickerStartDate.SelectedDate.Value);

				// Update summary
				_updateSummary();

			}
			m_bBlockEvents = false;

			// Send event
			if (ParametersChanged != null)
				ParametersChanged(this, e);

		}

		private void cboGenetive_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{

			// If blocking events...
			if (m_bBlockEvents)
				return;

			// block events
			m_bBlockEvents = true;
			{

				// Check the mode
				radMonthByWeek.IsChecked = true;

				// Get the parameters
				int iGenetive = (cboGenetive.SelectedItem as ComboBoxObject).ItemData;
				DayOfWeek dayOfTheWeek = (DayOfWeek) (cboMonthDayWeekday.SelectedItem as ComboBoxObject).ItemData;

				// Calculate the start-date
				pickerStartDate.SelectedDate = ExtensionsForDates.CalculateDate(DateTime.Now.Year, DateTime.Now.Month, iGenetive, dayOfTheWeek);

				// Set other controls
				ComboBoxObject.SelectByItemData(cboMonthDayOfMonth, pickerStartDate.SelectedDate.Value.Day);

			}
			m_bBlockEvents = false;

			// Send event
			if (ParametersChanged != null)
				ParametersChanged(this, e);

		}

		private void cboMonthDayWeekday_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{

			// If blocking events...
			if (m_bBlockEvents)
				return;

			// Call sibling function
			cboGenetive_SelectionChanged(sender, e);

			// Send event
			if (ParametersChanged != null)
				ParametersChanged(this, e);

		}

		private void radMonthByDate_Checked(object sender, RoutedEventArgs e)
		{

			// If blocking events...
			if (m_bBlockEvents)
				return;

			// Update summary
			_updateSummary();

			// Send event
			if (ParametersChanged != null)
				ParametersChanged(this, e);

		}

		private void radMonthByWeek_Checked(object sender, RoutedEventArgs e)
		{

			// If blocking events...
			if (m_bBlockEvents)
				return;

			// Update summary
			_updateSummary();

			// Send event
			if (ParametersChanged != null)
				ParametersChanged(this, e);

		}

		private void DatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
		{

			// Shortcuts
			if (m_bBlockEvents)
				return;

			// Block changes...
			m_bBlockEvents = true;
			{

				// Get the selected date
				DateTime dtStart = pickerStartDate.SelectedDate.Value;

				// Recalc day of month
				ComboBoxObject.SelectByItemData(cboMonthDayOfMonth, dtStart.Day);

				// Update controls
				_setMonthByWeekControls(dtStart);

				// Update summary
				_updateSummary();

			}
			m_bBlockEvents = false;

			// Send event
			if (ParametersChanged != null)
				ParametersChanged(this, e);

		}

		private void butArrow_Click(object sender, EventArgs e)
		{

			// if needs raising...
			if (gridForms.Height > 0)
			{
				animRaiseForms.Begin();
				butArrow.IsUpsideDown = true;
			}
			else
			{
				animDropForms.Begin();
				butArrow.IsUpsideDown = false;
			}

		}

		/////////////////////////////////////////////////////////////
		// Operations

		private void _setMonthByWeekControls(DateTime dtStart)
		{

			// Calc day of week
			DayOfWeek dayOfWeek = dtStart.DayOfWeek;
			if ((dayOfWeek == DayOfWeek.Saturday) || (dayOfWeek == DayOfWeek.Sunday))
				dayOfWeek = DayOfWeek.Friday;
			ComboBoxObject.SelectByItemData(cboMonthDayWeekday, (int)dayOfWeek);

			// Count which week
			ComboBoxObject.SelectByItemData(
				cboGenetive,
				ExtensionsForDates.CountWeekDay(dtStart)
			);

		}

		private void _setupControls()
		{

			// Show/hide controls
			monthStackA.Visibility = (
				(m_Period == Frequency.ePeriod.Monthly)
			) ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
			monthStackB.Visibility = monthStackA.Visibility;

		}

		public void Set(Frequency frequency)
		{

			// Block events
			m_bBlockEvents = true;
			{

				// Retain the period
				m_Period = frequency.PeriodFlags & Frequency.ePeriod.PeriodMask;

				// Get period
				if (
					(m_Period == Frequency.ePeriod.Weekly)
					||
					(m_Period == Frequency.ePeriod.Biweekly)
				)
				{

					// No parameters

				}
				else if (m_Period == Frequency.ePeriod.Monthly)
				{
					if (frequency.IsMonthlyByDate)
						radMonthByDate.IsChecked = true;
					else
						radMonthByDate.IsChecked = false;
				}
#if DEBUG
				else
					Debug.Assert(false);
#endif // #if DEBUG

			}
			m_bBlockEvents = false;

			// Set start date
			pickerStartDate.SelectedDate = frequency.Start;

			// Setup controls
			_setupControls();

			// Update summary
			_updateSummary();

		}

		public Frequency Get()
		{

			// Populate the frequency details object with details from the control

			// Declare return variable
			Frequency Ftmp;

			// Call form function
			if (
				(m_Period == Frequency.ePeriod.Weekly)
				||
				(m_Period == Frequency.ePeriod.Biweekly)
			)
				Ftmp = new Frequency(m_Period,pickerStartDate.SelectedDate.Value);
			else if (m_Period == Frequency.ePeriod.Monthly)
			{
				if(radMonthByDate.IsChecked ?? false)
					Ftmp = new Frequency(Frequency.ePeriod.Monthly | Frequency.ePeriod.Monthly_ByDate, pickerStartDate.SelectedDate.Value);
				else
					Ftmp = new Frequency(Frequency.ePeriod.Monthly | Frequency.ePeriod.Monthly_ByWeek, pickerStartDate.SelectedDate.Value);
			}
			else
			{
#if DEBUG
				Debug.Assert(false);
#endif // #if DEBUG
				Ftmp = null;
			}

			// Return variable
			return Ftmp; 

		}

		private void _updateSummary()
		{

			// Update the summary description from the current control values

			// Get details
			Frequency frequency = this.Get();

			// Compose summary
			tbSummaryA.Text = frequency.Start.ToString(Definitions.ShortDateFormat);
			tbSummaryB.Text = frequency.ComposeDescription();

		}

	}

}
